#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import sys
import threading

from common.const import ExecuteResultEnum, SubJobStatusEnum, ReportDBLabel
from common.common_models import ActionResult, LogDetail
from common.exception.common_exception import ErrCodeException
from common.number_const import NumberConst
from gaussdbt.single.comm.gst_single_error_code import ErrorCode
from gaussdbt.single.comm.utils.gst_single_param_utils import GstSingleParamUtil
from gaussdbt.single.restore.single_restore_base import SingleRestoreBase
from gaussdbt.single.restore.single_restore_service import SingleRestoreService
from gaussdbt.single import LOGGER


class SingleFullRestore(SingleRestoreBase):
    def __init__(self, pid, job_id, sub_job_id, job_param):
        super().__init__(pid, job_id, sub_job_id, job_param)
        self.os_user = GstSingleParamUtil.get_os_user("restore", self.pid, is_restore=True)

    def allow_restore_in_local_node(self):
        # 子任务不需要判断
        if self.job_param.get('subJob'):
            action_result = ActionResult(code=ExecuteResultEnum.SUCCESS).dict(by_alias=True)
            LOGGER.info('Sub job no need check, jobId=%s, subJobId=%s', self.job_id, self.sub_job_id)
            return action_result
        single_restore_service_instance = SingleRestoreService(self.pid, self.job_id, self.sub_job_id,
            self.job_param, self.os_user)
        if not single_restore_service_instance.is_version_matched():
            action_result = ActionResult(code=ExecuteResultEnum.INTERNAL_ERROR,
                bodyErr=ErrorCode.VERSION_NOT_MATCH_BEFORE_RESTORE).dict(by_alias=True)
            return action_result
        action_result = ActionResult(code=ExecuteResultEnum.SUCCESS).dict(by_alias=True)
        return action_result

    def exec_restore_pre(self):
        # 前置任务直接上报完成
        single_restore_service_instance = SingleRestoreService(self.pid, self.job_id, self.sub_job_id,
            self.job_param, self.os_user)
        single_restore_service_instance.report_job_completed()

    def exec_restore(self):
        LOGGER.info('Start exec restore, jobId=%s, subJobId=%s', self.job_id, self.sub_job_id)
        single_restore_service_instance = SingleRestoreService(self.pid, self.job_id, self.sub_job_id,
            self.job_param, self.os_user)
        single_restore_service_instance.job_datails = [
            LogDetail(logInfo=ReportDBLabel.RESTORE_SUB_START_COPY, logInfoParam=[self.sub_job_id], logLevel=1)
        ]
        progress_thread = threading.Thread(name="progress", target=single_restore_service_instance.report_progress)
        # 任务意外结束时子线程也结束任务
        progress_thread.daemon = True
        progress_thread.start()
        ret, restore_param = single_restore_service_instance.get_full_restore_param()
        if not ret:
            single_restore_service_instance.job_status = SubJobStatusEnum.FAILED
            LOGGER.error('Get full restore param failed, jobId=%s, subJobId=%s', self.job_id, self.sub_job_id)
            progress_thread.join()
            return False
        single_restore_service_instance.exec_full_restore(restore_param)
        LOGGER.info('Restore exec success, jobId=%s, subJobId=%s', self.job_id, self.sub_job_id)
        single_restore_service_instance.job_status = SubJobStatusEnum.COMPLETED
        single_restore_service_instance.job_datails = [
            LogDetail(logInfo=ReportDBLabel.SUB_JOB_SUCCESS, logInfoParam=[self.sub_job_id], logLevel=1)
        ]
        progress_thread.join()
        return True

    def exec_restore_post(self):
        # 后置任务无清理操作，直接上报完成
        single_restore_service_instance = SingleRestoreService(self.pid, self.job_id, self.sub_job_id,
            self.job_param, self.os_user)
        single_restore_service_instance.report_job_completed()